#pragma once

#include "ParameterableElement.h"

#include "TemplateParameter.h"

namespace uml {

void ParameterableElement::fromJson(const QJsonObject& json, QStringList& errorList) {
    if (json.isEmpty()) {
        return;
    }

    PartialElement::fromJson(json, errorList);
    owningTemplateParameter_ = JsonSerializable::create<TemplateParameter>(json.value("owningTemplateParameter"), errorList);

    templateParameter_ = JsonSerializable::create<TemplateParameter>(json.value("templateParameter"), errorList);

}

void ParameterableElement::toJson(QJsonObject& json) {
    PartialElement::toJson(json);
    if (owningTemplateParameter_) {
        QJsonObject owningTemplateParameter_json;
        owningTemplateParameter_->toJson(owningTemplateParameter_json);
        json.insert("owningTemplateParameter", owningTemplateParameter_json);
    }
    if (templateParameter_) {
        QJsonObject templateParameter_json;
        templateParameter_->toJson(templateParameter_json);
        json.insert("templateParameter", templateParameter_json);
    }
}

/// <summary>
/// isCompatibleWith
    /// The query isCompatibleWith() determines if this ParameterableElement is
    /// compatible with the specified ParameterableElement. By default, this
    /// ParameterableElement is compatible with another ParameterableElement p if the
    /// kind of this ParameterableElement is the same as or a subtype of the kind of p.
    /// Subclasses of ParameterableElement should override this operation to specify
    /// different compatibility constraints.
/// </summary>
    /// <code>
    /// result = (self.oclIsKindOf(p.oclType()))
    /// </code>
bool ParameterableElement::isCompatibleWith(shared_ptr<ParameterableElement> p) const
{
    return false;
}

/// <summary>
/// isTemplateParameter
    /// The query isTemplateParameter() determines if this ParameterableElement is
    /// exposed as a formal TemplateParameter.
/// </summary>
    /// <code>
    /// result = (templateParameter->notEmpty())
    /// </code>
bool ParameterableElement::isTemplateParameter() const
{
    return false;
}

/// <summary>
/// owningTemplateParameter getter
/// The formal TemplateParameter that owns this ParameterableElement.
/// </summary>
shared_ptr<TemplateParameter> ParameterableElement::owningTemplateParameter() const {
    return owningTemplateParameter_;
}

/// <summary>
/// owningTemplateParameter setter
/// The formal TemplateParameter that owns this ParameterableElement.
/// </summary>
void ParameterableElement::setOwningTemplateParameter(shared_ptr<TemplateParameter> value) {
    owningTemplateParameter_ = value;
}

/// <summary>
/// templateParameter getter
/// The TemplateParameter that exposes this ParameterableElement as a formal
/// parameter.
/// </summary>
shared_ptr<TemplateParameter> ParameterableElement::templateParameter() const {
    return templateParameter_;
}

/// <summary>
/// templateParameter setter
/// The TemplateParameter that exposes this ParameterableElement as a formal
/// parameter.
/// </summary>
void ParameterableElement::setTemplateParameter(shared_ptr<TemplateParameter> value) {
    templateParameter_ = value;
}

} // namespace uml
